

#include "StateMachine/StateMachine.h"

#include <filesystem>

#include "StateMachine/State.h"
#include "InputActionValue.h"
#include "Core/Character2D.h"

void UStateMachine::Init(APlayerController* Controller, ACharacter2D* Player)
{
	PlayerController = Controller;
	Character = Player;
	CleanStates();
}

void UStateMachine::Tick(float DeltaTime)
{
	if (CurrentState)
	{
		CurrentState->Tick(DeltaTime);
	}
}

void UStateMachine::SwitchState(UState* NewState)
{
	if (CurrentState)
		CurrentState->Exit();
	CurrentState = NewState;
	CurrentState->Enter();
}

void UStateMachine::SwitchState(const TSubclassOf<UState>& StateClass)
{
	UState* NewState = GetState(StateClass);
	if (!NewState)
	{
		UE_LOG(LogTemp, Warning, TEXT("SwitchState: %s 状态不存在"), *StateClass->GetName())
		return;
	}
	SwitchState(NewState);
}

void UStateMachine::InputSignal(EInputSignal Signal, const FInputActionValue& Value)
{
	FString StateName = CurrentState ? CurrentState->GetName() : "NULL";
	UE_LOG(LogTemp, Display, TEXT("状态机收到输入信号: %d！当前状态：%s"), Signal, *StateName);
	if (CurrentState)
	{
		CurrentState->InputSignal(Signal, Value);
	}
}


void UStateMachine::CleanStates()
{
	StateMap.Empty();
}

UStateMachine* UStateMachine::AddState(UState* StateInstance)
{
	ensure(StateInstance);
	UClass* StateClass = StateInstance->GetClass();
	if (!StateClass->IsChildOf(UState::StaticClass()))
	{
		UE_LOG(LogTemp, Error, TEXT("AddState: %s 对象的类型不是UState的子类"), *StateClass->GetName());
		return this;
	}
	StateMap.Emplace(StateClass, StateInstance);
	return this;
}

UStateMachine* UStateMachine::AddState(const TSubclassOf<UState>& StateClass)
{
	if (StateClass && StateClass->IsChildOf(UState::StaticClass()))
	{
		UState* StateInstance = NewObject<UState>(StateClass);
		ensure(StateInstance);
		StateInstance->Init(PlayerController, Character, this);
		StateMap.Emplace(StateClass, StateInstance);
	}
	return this;
}

UState* UStateMachine::GetState(const TSubclassOf<UState>& StateClass) const
{
	if (StateClass && StateMap.Contains(StateClass))
	{
		return StateMap[StateClass];
	}
	return nullptr;
}



